﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using Domain.Entity;

namespace Infrastructure.Data.Uow
{
    public partial class UnitOfWorkContext : DbContext, UnitOfWorkIQueryable
    {
        public void Commit()
        {
            try
            {
                base.SaveChanges();
            }
            catch (Exception ex)
            {
                Infrastructure.Data.Uow.Log.LoggerRepositoryManager.AddLogInfo(1, 0, string.Empty, string.Empty,
                    "commit data error " + ex.Message, ex.InnerException != null ? ex.InnerException.Message : string.Empty, string.Empty);
            }
        }

        public void Refresh()
        {
            bool saveFailed = false;
            do
            {
                try
                {
                    base.SaveChanges();
                }
                catch (DbUpdateConcurrencyException ex)
                {
                    Infrastructure.Data.Uow.Log.LoggerRepositoryManager.AddLogInfo(1, 0, string.Empty, string.Empty,
                        "commit data and refresh data error " + ex.Message, ex.InnerException != null ? ex.InnerException.Message : string.Empty, string.Empty);
                    saveFailed = true;

                    ex.Entries.ToList()
                        .ForEach(entry => { entry.OriginalValues.SetValues(entry.GetDatabaseValues()); });
                }
            } while (saveFailed);
        }

        public void Rollback()
        {
            base.ChangeTracker.Entries().ToList().ForEach(entry => entry.State = System.Data.EntityState.Unchanged);

            Infrastructure.Data.Uow.Log.LoggerRepositoryManager.AddLogInfo(1, 0, string.Empty, string.Empty,
                    "rollback data", string.Empty, string.Empty);
        }

        #region UnitOfWorkIQueryable

        public IDbSet<T> SetEntity<T>() where T : Domain.Entity.EntityBase
        {
            return base.Set<T>();
        }

        public IEnumerable<TEntity> ExecuteQuery<TEntity>(string sqlQuery, params object[] parameters)
        {
            Infrastructure.Data.Uow.Log.LoggerRepositoryManager.AddLogInfo(1, 0, string.Empty, string.Empty,
                   "execute query", "execute query " + sqlQuery, string.Empty);

            return base.Database.SqlQuery<TEntity>(sqlQuery, parameters);
        }

        public int ExecuteCommand(string sqlCommand, params object[] parameters)
        {
            Infrastructure.Data.Uow.Log.LoggerRepositoryManager.AddLogInfo(1, 0, string.Empty, string.Empty,
                   "execute command", "execute command " + sqlCommand, string.Empty);

            return base.Database.ExecuteSqlCommand(sqlCommand, parameters);
        }

        #endregion
    }
}
